package co.fitstart.market.web.resolver;

import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.ModelAttributeMethodProcessor;
import org.springframework.web.util.WebUtils;

import co.fitstart.market.Constant;
import co.fitstart.market.entity.UserContext;

/**
 * 
 * @author downpour
 */
public class UserContextAgrumentResolver extends ModelAttributeMethodProcessor {

    private static final Logger logger = LoggerFactory.getLogger(UserContextAgrumentResolver.class);

    private String openidKey = Constant.OPENID_KEY;
    
    private String mobileKey = Constant.MOBILE_KEY;
    
    private String accountIdKey = Constant.USER_ACCOUNT_KEY;
    
    /**
     * @param openidKey The openidKey to set
     */
    public void setOpenidKey(String openidKey) {
        this.openidKey = openidKey;
    }
    
    /**
     * @param mobileKey The mobileKey to set
     */
    public void setMobileKey(String mobileKey) {
        this.mobileKey = mobileKey;
    }
    
    /**
     * @param annotationNotRequired
     */
    public UserContextAgrumentResolver(boolean annotationNotRequired) {
        super(annotationNotRequired);
    }

    /* (non-Javadoc)
     * @see org.springframework.web.method.annotation.ModelAttributeMethodProcessor#supportsParameter(org.springframework.core.MethodParameter)
     */
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserContext.class);
    }

    /* (non-Javadoc)
     * @see org.springframework.web.method.annotation.ModelAttributeMethodProcessor#createAttribute(java.lang.String, org.springframework.core.MethodParameter, org.springframework.web.bind.support.WebDataBinderFactory, org.springframework.web.context.request.NativeWebRequest)
     */
    protected Object createAttribute(String attributeName, MethodParameter methodParam, WebDataBinderFactory binderFactory, NativeWebRequest webRequest) throws Exception {
        
        // Transform NativeWebRequest to HttpServletRequest
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        
        UserContext userContext = new UserContext();
        
        // Get mobile cookie
        Cookie mobileCookie = WebUtils.getCookie(request, this.mobileKey);
        
        if(mobileCookie != null) {
            
            String mobile = mobileCookie.getValue();
            
            logger.trace("#resolveArgument, get mobile from cookie with key [{}] and cookie value [{}]", this.mobileKey, mobile);
        
            // init mobile
            userContext.mobile(mobile);
        }
        
        // Get openid cookie
        Cookie openidCookie = WebUtils.getCookie(request, this.openidKey);
        
        if(openidCookie != null) {
            
            String openid = openidCookie.getValue();
            
            logger.trace("#resolveArgument, get openid from cookie with openidKey [{}] and cookie value [{}]", this.openidKey, openid);
            
            userContext.openid(openid);
        
        }
        
        // Get accountId cookie
        Cookie accountCookie = WebUtils.getCookie(request, this.accountIdKey);
        
        if(accountCookie != null) {
            
            String accountId = accountCookie.getValue();
            
            logger.trace("#resolveArgument, get accountId from cookie with accountIdKey [{}] and cookie value [{}]", this.accountIdKey, accountId);
            
            userContext.accountId(accountId);
        
        }
        
        return userContext;
    }
    
    /* (non-Javadoc)
     * @see org.springframework.web.method.annotation.ModelAttributeMethodProcessor#bindRequestParameters(org.springframework.web.bind.WebDataBinder, org.springframework.web.context.request.NativeWebRequest)
     */
    protected void bindRequestParameters(WebDataBinder binder, NativeWebRequest request) {
        ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
        ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
        servletBinder.bind(servletRequest);
    }
    
}
